package org.agile.grenoble.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.agile.grenoble.configuration.Configuration;
import org.agile.grenoble.configuration.Messages;
import org.agile.grenoble.questions.AnswerType;
import org.agile.grenoble.questions.AnswersType;
import org.agile.grenoble.questions.ConfigurationType;
import org.agile.grenoble.questions.QuestionType;
import org.agile.grenoble.questions.QuestionsType;

class MyActionLogicListener implements ActionListener, ChangeListener {

	
	AnswerType at = null; 
	public MyActionLogicListener(AnswerType pAt) {
		at = pAt ;
	}

//	@Override
	public void actionPerformed(ActionEvent arg0) {
		//select or not select ? 
		AbstractButton ab = (AbstractButton) arg0.getSource();
		if (ab.isSelected()== true) {
			at.setSelected(AnswerType.Selected.TRUE);				
		} else{
			at.setSelected(AnswerType.Selected.FALSE);
		}
		//System.out.println("Yeh, a action is performed , my model should be updated :"  +at.getLabel()) ;
	}
	

//	@Override
	public void stateChanged(ChangeEvent arg0) {
		//occure too often, seems selected/unselected/highligth/unhighlight
		//select or not select ? 
		AbstractButton ab = (AbstractButton) arg0.getSource();
		if (ab.isSelected()== true) {
			at.setSelected(AnswerType.Selected.TRUE);				
		} else{
			at.setSelected(AnswerType.Selected.FALSE);
		}
		//System.out.println("Yeh, a state change is detected, my model should be updated :" +at.getLabel() + "/" + at.getSelected()) ;
	}

}


/*
 * myCheckGroup handle the logic of a set of checkbox,
 * with a maximun number of selected elements
 */
class MyCheckGroup implements ActionListener {
	
	int iMaxSelected = -1 ;
	int iNbCheckedItem = 0 ;
	Vector<JCheckBox> v = new Vector<JCheckBox>();
	
	/*
	 * maximun of element selectable in this group
	 */
	MyCheckGroup(int maxSelected) {
		iMaxSelected = maxSelected ; 
	}
	
	/* 
	 * add a checkbox to this list of elements
	 */
	public void add(JCheckBox aBox) {
	  aBox.addActionListener(this);
	  v.add(aBox);
	}

	/*
	 * when clicking on a checkbox, checks if max is reached. And forbid the selection 
	 * if max is reached. 
	 * note : allow unselection of elements
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
//	@Override
	public void actionPerformed(ActionEvent arg0) {
		//select or not select ? 
		JCheckBox cb = (JCheckBox) arg0.getSource();
		if (cb.isSelected())
		{
			iNbCheckedItem++;
			if (iNbCheckedItem > iMaxSelected) {
				for ( Enumeration<JCheckBox> e = v.elements(); e.hasMoreElements(); ) {
					JCheckBox value = e.nextElement();
					if (value == cb) {
						iNbCheckedItem--;
						value.setSelected(false);
						//display each vegetable
						System.out.println( value );
					}
				 }
			} else if (iNbCheckedItem < iMaxSelected) {
				//nothing
			} else {
				//nothing
			}
		} else {
			//unselect 
			iNbCheckedItem--;
		}
		
	}
	
}

/*
 * main graphical class
 * */

public class NokiaSwing extends JFrame {

  private static final int globalHeight = 550;
  private static final int globalWidth = 600;
  /**
   * 
   */
  private static final long serialVersionUID = -8322709712160036058L;

  public NokiaSwing() {
    super();
    setTitle("Be ready for the question");
    initContent();
  }

  private void initContent() {
    setTitle("Nokia Test");
  }
  JPanel[] iPanel = null;
  JPanel iNavBar = null;
  JButton nextOrTerminate = null;
  JPanel welcome = null;

  //temporary 
  public void generateQuestionDisplay(QuestionsType pQuestions) throws InstantiationException {
    //JPanel questionArea = new JPanel();
    iPanel = generateQuestionsPanels(pQuestions);

    //welcome = HomePage(); 
    //getContentPane().add(welcome);
    getContentPane().setBackground(Color.lightGray);
    iNavBar = generateNavigationBar();

    pack();
    repaint();
  }

  /* 
   * Navigation Bar (may be a standalone class soon )
   * */
  public JPanel generateNavigationBar() {
    JPanel navigationBar = new JPanel();
    nextOrTerminate = new JButton("NextorTerminate");
    navigationBar.add(nextOrTerminate, BorderLayout.EAST);
    return navigationBar;
  }

  /* 
   * Took a list of question, and build the panel. There's a panel per question.
   * */
  private JPanel[] generateQuestionsPanels(QuestionsType pQuestions) throws InstantiationException {
    JPanel[] questionsPanels = new JPanel[pQuestions.getQuestionArray().length];

    for (int i = 0; i < pQuestions.getQuestionArray().length; i++) {
      questionsPanels[i] = generateQuestionPanel(pQuestions.getQuestionArray()[i]);

    }
    return questionsPanels;
  }

  //private static final String	FILENAME = "src/resources/images/question.JPG";
  /** 
   * We return a panel per question, allowing us to display several panel in the same page
   * or one panel per page ... 
   * May be the change is the "Next " button inside the panel or outside it 
   * @throws Exception 
   * */
  private JPanel generateQuestionPanel(QuestionType pQuestion) throws InstantiationException {
    JPanel questionContainer = generateQuestionArea();
    if (pQuestion.getConfiguration().getType() != ConfigurationType.Type.COMPLEXE) {

      questionContainer.setLayout(new GridLayout(pQuestion.getAnswers().getAnswerArray().length + 1,
        1));

      Label questionText = new Label(pQuestion.getLabel());
      questionContainer.add(questionText);
      JLabel questionMark = Utils.getImage(Configuration.getString("NokiaTest.questionLogo"));

      JPanel questionPanel = new JPanel();

      //questionPanel.setLayout(new GridLayout(1, 2));
      questionPanel.setLayout(new FlowLayout());

      Font font = new Font("sansserif", Font.BOLD, 20);

      //questionText.setBackground(Color.blue);
      questionText.setForeground(Color.blue);
      //questionMark.setBackground(Color.blue);

      questionText.setFont(font);
      //Dimension minimumSize= new Dimension(500,75);
      //questionText.setMinimumSize(minimumSize);


      GridBagConstraints c = new GridBagConstraints();


      //c.weightx = 1.0;
      c.gridwidth = GridBagConstraints.RELATIVE;

      questionPanel.add(questionText);
      questionPanel.add(questionMark);

      questionContainer.add(questionPanel);
      addAnswers(pQuestion.getConfiguration(), pQuestion.getAnswers(), questionContainer);
    } else {
      //the question if made of several question 
      JPanel childrenPanel = null;
      questionContainer.setLayout(new GridLayout(pQuestion.getQuestionArray().length, 1));
      for (int i = 0; i < pQuestion.getQuestionArray().length; i++) {
        childrenPanel = generateQuestionPanel(pQuestion.getQuestionArray()[i]);
        questionContainer.add(childrenPanel);
      } //end for 
    } //end if 	

    return questionContainer;
  }

  /*
   *  add answers to the question panel.
   * 
   */
  private void addAnswers(ConfigurationType conf, AnswersType pAnswers, JPanel questionContainer)
    throws InstantiationException {
    if (conf == null || conf.getType() == null) {
      //don't add anything
      return;
    }
    if (conf.getType() == ConfigurationType.Type.SINGLE) {
      addRadioAnswers(pAnswers, questionContainer);
    } else if (conf.getType() == ConfigurationType.Type.MULTIPLE) {
      addCheckAnswers(conf, pAnswers, questionContainer);
    } else {
      //ERROR 
      throw new InstantiationException("UNKNOWN question type :" + conf.getType());
    }
  }

  /* 
   * Add check box button look answers
   * 
   */
  private void addCheckAnswers(ConfigurationType conf, AnswersType pAnswers,
    JPanel questionContainer) {
    MyCheckGroup buttonGroup = new MyCheckGroup(conf.getNumber());

    for (int i = 0; i < pAnswers.getAnswerArray().length; i++) {
      String answer = pAnswers.getAnswerArray()[i].getLabel();
      JCheckBox answerText = new JCheckBox(answer);
      //listen to click / unclick 
      answerText.addChangeListener(new MyActionLogicListener(pAnswers.getAnswerArray()[i]));
      questionContainer.add(answerText);
      buttonGroup.add(answerText);
    }
  }

  /* 
   * Add radio button look answers
   * 
   */
  private void addRadioAnswers(AnswersType pAnswers, JPanel questionContainer) {
    ButtonGroup buttonGroup = new ButtonGroup();

    for (int i = 0; i < pAnswers.getAnswerArray().length; i++) {
      String answer = pAnswers.getAnswerArray()[i].getLabel();
      JRadioButton answerText = new JRadioButton(answer);
      questionContainer.add(answerText);
      //listen to click / unclick
      answerText.addChangeListener(new MyActionLogicListener(pAnswers.getAnswerArray()[i]));
      buttonGroup.add(answerText);
    }
  }

  private JPanel generateQuestionArea() {
    JPanel questionArea = new JPanel();
    // Preferred height is irrelevant, since using WEST region

    questionArea.setPreferredSize(new Dimension(globalHeight, globalWidth));
    questionArea.setBorder(BorderFactory.createLineBorder(Color.blue, 2));
    questionArea.setBackground(Color.white);
    return questionArea;
  }

  @SuppressWarnings("deprecation")
  public void displayFirstquestion() {
    getContentPane().setBackground(Color.lightGray);
    //TODO remove welcome message
    //getContentPane().remove(welcome);
    getContentPane().add(iPanel[0], BorderLayout.NORTH);
    //TODO add i18n
    //BUG
    //nextOrTerminate.setLabel("Next");
    nextOrTerminate.setLabel(Messages.getString("NokiaTest.next"));
    getContentPane().add(iNavBar, BorderLayout.SOUTH);
    pack();
    repaint();

  }

  public void registerOnClickNavBarEvent(NokiaControler nokiaControler) {
    nextOrTerminate.addActionListener(nokiaControler);
  }

  public void nextQuestion(int currentQuestionIndex, boolean isLast) {
    getContentPane().remove(iPanel[currentQuestionIndex - 1]);
    getContentPane().add(iPanel[currentQuestionIndex], BorderLayout.NORTH);
    //TODO add i18n
    if (isLast) {
      nextOrTerminate.setLabel(Messages.getString("NokiaTest.goHome"));
    } else {
      nextOrTerminate.setLabel(Messages.getString("NokiaTest.next"));
    }
    //getContentPane().add(iNavBar, BorderLayout.SOUTH );
    pack();
    repaint();

  }

  public void TerminateTest() {
    dispose();

  }
}
